﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ProgramTest
{
    public static class LambdaShow
    {
        public static void Show()
        {
            {
                // var result = matrixVectorProductAsync(...);
                Func<double, double, Task<double>> matrixVectorProductAsync = async (x, y) =>
                {
                    var sum = 0.0;
                    /* do some stuff using await ... */
                    return sum;
                };
            }
            {
                LambdaTempClass tempClass = new LambdaTempClass();
                tempClass.DoSomeStuff();
            }
            {
                //new Random().NextDouble()
            }
            {
                ////有错误：lambda表达式不能直接分配给匿名类型属性
                ////Create anonymous object
                //var person = new
                //{
                //    Name = "Jesse",
                //    Age = 28,
                //    Ask = (string question) =>
                //    {
                //        Console.WriteLine("The answer to `" + question + "` is certainly 42!");
                //    }
                //};

                ////Execute function
                //person.Ask("Why are you doing this?");
            }
            {
                //如果想在匿名类型中应用当前类型的属性，可以用dynamic关键字
                dynamic person = null;
                person = new
                {
                    Name = "Jesse",
                    Age = 28,
                    Ask = (Action<string>)((string question) =>
                    {
                        Console.WriteLine("The answer to `" + question + "` is certainly 42! My age is " + person.Age + ".");
                    })
                };

                //Execute function
                person.Ask("Why are you doing this?");
            }

            {

            }
            Console.ReadKey();
        }

    }

    public class LambdaTempClass
    {
        public void DoSomeStuff()
        {
            var coeff = 10;
            Func<int, int> compute = x => coeff * x;
            Action modifier = () =>
            {
                coeff = 5;
            };

            var result1 = DoMoreStuff(compute);

            ModifyStuff(modifier);

            var result2 = DoMoreStuff(compute);
        }

        int DoMoreStuff(Func<int, int> computer)
        {
            return computer(5);
        }

        void ModifyStuff(Action modifier)
        {
            modifier();
        }
    }

    public static class LambdaTempClass2
    {
        static Dictionary<string, Action> finalizers;

        // 在静态的构造函数用调用这个方法
        public static void BuildFinalizers()
        {
            finalizers = new Dictionary<string, Action>();

            // 获得当前运行程序集下所有的类型
            var types = Assembly.GetExecutingAssembly().GetTypes();

            foreach (var type in types)
            {
                // 检查类型，我们可以提前定义接口或抽象类
                //if (type.IsSubclassOf(typeof(MyMotherClass)))
                //{
                //    // 获得默认无参构造函数
                //    var m = type.GetConstructor(Type.EmptyTypes);

                //    // 调用这个默认的无参构造函数
                //    if (m != null)
                //    {
                //        var instance = m.Invoke(null) as MyMotherClass;
                //        var name = type.Name.Remove("Mother");
                //        var method = instance.MyMethod;
                //        finalizers.Add(name, method);
                //    }
                //}
            }
        }

        public static Action GetFinalizer(string input)
        {
            if (finalizers.ContainsKey(input))
                return finalizers[input];

            return () => { /* ... */ };
        }
    }
}
